﻿using gt.rediscache.logger;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Net;
using System.Threading.Tasks;

namespace gt.rediscache.plugins
{
    /// <summary>
    /// redis client 异常警报
    /// </summary>
    public class RedisClientNotifyer
    {
        private ConcurrentDictionary<string, string> _notifyEventContainer = new ConcurrentDictionary<string, string>();
        private const string _msgTitle = "Redis Cache";
        private const string _msgType = "RedisSmartClient";

        private string _idc = string.Empty;
        private string _notifyUrl = string.Empty;
        public RedisClientNotifyer()
        {

        }

        public void SetNotifyUrl(string idc, string notifyUrl)
        {
            _idc = idc;
            _notifyUrl = notifyUrl;
        }

        public void NotifyAsync(string message, string nodeName, bool restoreMsg)
        {
            if (string.IsNullOrEmpty(_notifyUrl)) return;

            JObject j = new JObject();
            j["MonitorType"] = _msgType;
            j["EventType"] = 1;
            j["Detail"] = message;
            j["EventTime"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm");
            j["HostName"] = GetLocalIp();
            j["IDC"] = _idc;
            j["MonitorSource"] = 2;
            j["TriggerItem"] = _msgTitle;
            if (restoreMsg && _notifyEventContainer.Keys.Contains(nodeName)) j["EventId"] = _notifyEventContainer[nodeName];

            Task.Run(() =>
            {
                try
                {
                    string result = HttpClientUtility.Post(_notifyUrl, JsonConvert.SerializeObject(j));
                    if (!restoreMsg)
                        _notifyEventContainer.TryAdd(nodeName, result);
                    RedisLogManager.Info(string.Format("msg: {0} send success,result:{1}", message, result));
                }
                catch (Exception ex)
                {
                    RedisLogManager.Error(string.Format("msg: {0} send failed,error:{1}", message, ex.Message + ex.StackTrace));
                }
            });
        }

        private static string localIp = string.Empty;
        private static object _obj = new object();
        private string GetLocalIp()
        {
            if (string.IsNullOrEmpty(localIp))
            {
                lock (_obj)
                {
                    if (string.IsNullOrEmpty(localIp))
                    {
                        var ipArray = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
                        if (ipArray != null && ipArray.Length > 0)
                        {
                            var ip4 = ipArray.FirstOrDefault(p => p.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork);
                            if (ip4 != null)
                            {
                                localIp = ip4.ToString();
                            }
                        }
                    }
                }
            }
            return localIp;
        }
    }
}
